home *** CD-ROM | disk | FTP | other *** search
- #define LIBQTOOLS_CORE
- #include "../include/libqtools.h"
- #include "../include/libqbuild.h"
- #include "TDDD.h"
-
- #define CLUSTER_POINTS (CLUSTER_FACES / 3)
- #define CLUSTER_GROUPS 16
- #define CLUSTER_SUBGROUP (CLUSTER_FACES / 3)
-
- int TDDDmax_pcount = 0;
- int TDDDmax_ecount = 0;
- int TDDDmax_tcount = 0;
- int TDDDmax_gcount = 0;
- struct points *TDDDpoints = 0;
- struct edges *TDDDedges = 0;
- struct faces *TDDDfaces = 0;
- int TDDDgroups = 0;
- int *TDDDgroupsizes = 0;
- struct facesubgroup **TDDDgroup = 0;
- struct brush5 *TDDDbrushes = 0;
-
- int TDDDnumpoints = 0;
- int TDDDnumedges = 0;
- int TDDDnumfaces = 0;
- int TDDDnumgroups = 0;
- int TDDDnumobjects = 0;
-
- int nummapbrushes; // 4
-
- void AllocTDDDSubGroup(register int faceNum, register char *texname)
- {
- unsigned short int i, j;
-
- if (!TDDDgroup) {
- if (!(TDDDgroup = (struct facesubgroup **)tmalloc(CLUSTER_GROUPS * sizeof(struct facesubgroup *))))
- Error("AllocGroup: failed to allocate group!\n");
- if (!(TDDDgroupsizes = (int *)tmalloc(CLUSTER_GROUPS * sizeof(int))))
- Error("AllocGroup: failed to allocate group!\n");
- if (!(TDDDbrushes = (struct brush5 *)tmalloc(CLUSTER_GROUPS * sizeof(struct brush5))))
- Error("AllocGroups: failed to allocate brush!\n");
- }
-
- if (TDDDgroups >= TDDDmax_gcount) {
- if (!(TDDDgroup = (struct facesubgroup **)trealloc(TDDDgroup, ((TDDDmax_gcount += CLUSTER_GROUPS) * sizeof(struct facesubgroup *)))))
- Error("AllocGroup: failed to reallocate group!\n");
- if (!(TDDDgroupsizes = (int *)trealloc(TDDDgroupsizes, (TDDDmax_gcount * sizeof(int)))))
- Error("AllocGroup: failed to reallocate group!\n");
- if (!(TDDDbrushes = (struct brush5 *)trealloc(TDDDbrushes, (TDDDmax_gcount * sizeof(struct brush5)))))
- Error("AllocGroup: failed to reallocate brush!\n");
- }
-
- for (i = 0; i < TDDDgroups; i++)
- if(!strncmp(TDDDgroup[i]->name, texname, 18))
- break;
-
- if (!TDDDgroup[i])
- if (!(TDDDgroup[i] = (struct facesubgroup *)tmalloc((CLUSTER_SUBGROUP * sizeof(unsigned short int)) + sizeof(struct facesubgroup))))
- Error("AllocGroup: failed to allocate subgroup!\n");
-
- if (TDDDgroup[i]->count >= TDDDgroupsizes[i])
- if (!(TDDDgroup[i] = (struct facesubgroup *)trealloc(TDDDgroup[i], ((TDDDgroupsizes[i] += CLUSTER_SUBGROUP) * sizeof(unsigned short int)) + sizeof(struct facesubgroup))))
- Error("AllocGroup: failed to reallocate subgroup!\n");
-
- if (i == TDDDgroups) {
- strncpy(TDDDgroup[i]->name, texname, 18);
- TDDDbrushes[i].fullscale = 1;
- TDDDbrushes[i].flags = BRS_COLOR;
- TDDDbrushes[i].wflags = BRW_REPEA;
- TDDDgroups++;
- TDDDnumgroups++;
- }
-
- for (j = 0; j < TDDDgroup[i]->count; j++)
- if (faceNum == TDDDgroup[i]->facelist[j])
- return;
-
- TDDDgroup[i]->facelist[j] = faceNum;
- TDDDgroup[i]->count++;
- }
-
- unsigned short int AllocTDDDPoint(register vector * point)
- {
- unsigned short int i;
-
- if (!TDDDpoints)
- if (!(TDDDpoints = (struct points *)tmalloc((CLUSTER_POINTS * sizeof(vector)) + sizeof(struct points))))
- Error("AllocPoint: failed to allocate point!\n");
-
- if (TDDDpoints->pcount >= TDDDmax_pcount)
- if (!(TDDDpoints = (struct points *)trealloc(TDDDpoints, ((TDDDmax_pcount += CLUSTER_POINTS) * sizeof(vector)) + sizeof(struct points))))
- Error("AllocPoint: failed to reallocate point!\n");
-
- for (i = 0; i < TDDDpoints->pcount; i++) {
- if (point->x == TDDDpoints->points[i].x)
- if (point->y == TDDDpoints->points[i].y)
- if (point->z == TDDDpoints->points[i].z)
- return i;
- }
- TDDDpoints->points[i].x = point->x;
- TDDDpoints->points[i].y = point->y;
- TDDDpoints->points[i].z = point->z;
- TDDDpoints->pcount++;
- TDDDnumpoints++;
- return i;
- }
-
- unsigned short int AllocTDDDEdge(register unsigned short int point0, register unsigned short int point1)
- {
- unsigned short int i;
-
- if (!TDDDedges)
- if (!(TDDDedges = (struct edges *)tmalloc((CLUSTER_EDGES * sizeof(unsigned short int) * 2) + sizeof(struct edges))))
- Error("AllocEdge: failed to allocate edge!\n");
-
- if (TDDDedges->ecount >= TDDDmax_ecount)
- if (!(TDDDedges = (struct edges *)trealloc(TDDDedges, ((TDDDmax_ecount += CLUSTER_EDGES) * sizeof(unsigned short int) * 2) + sizeof(struct edges))))
- Error("AllocEdge: failed to reallocate edge!\n");
-
- for (i = 0; i < TDDDedges->ecount; i++) {
- if (point0 == TDDDedges->edges[i][0])
- if (point1 == TDDDedges->edges[i][1])
- return i;
- }
- TDDDedges->edges[i][0] = point0;
- TDDDedges->edges[i][1] = point1;
- TDDDedges->ecount++;
- TDDDnumedges++;
- return i;
- }
-
- unsigned short int AllocTDDDFace(register unsigned short int connect0, register unsigned short int connect1, register unsigned short int connect2)
- {
- unsigned short int i;
-
- if (!TDDDfaces)
- if (!(TDDDfaces = (struct faces *)tmalloc((CLUSTER_FACES * sizeof(unsigned short int) * 3) + sizeof(struct faces))))
- Error("AllocFace: failed to allocate face!\n");
-
- if (TDDDfaces->tcount >= TDDDmax_tcount)
- if (!(TDDDfaces = (struct faces *)trealloc(TDDDfaces, ((TDDDmax_tcount += CLUSTER_FACES) * sizeof(unsigned short int) * 3) + sizeof(struct faces))))
- Error("AllocFace: failed to reallocate face!\n");
-
- for (i = 0; i < TDDDfaces->tcount; i++) {
- if (connect0 == TDDDfaces->connects[i][0])
- if (connect1 == TDDDfaces->connects[i][1])
- if (connect2 == TDDDfaces->connects[i][2])
- return i;
- }
- TDDDfaces->connects[i][0] = connect0;
- TDDDfaces->connects[i][1] = connect1;
- TDDDfaces->connects[i][2] = connect2;
- TDDDfaces->tcount++;
- TDDDnumfaces++;
- return i;
- }
-
- bool SaveFace(vec3_t point0, vec3_t point1, vec3_t point2, register char *texname)
- {
- unsigned short int face, p0, p1, p2;
- vector p;
-
- p.x = float2fract(point0[0]);
- p.y = float2fract(point0[1]);
- p.z = float2fract(point0[2]);
- p0 = AllocTDDDPoint(&p);
- p.x = float2fract(point1[0]);
- p.y = float2fract(point1[1]);
- p.z = float2fract(point1[2]);
- p1 = AllocTDDDPoint(&p);
- p.x = float2fract(point2[0]);
- p.y = float2fract(point2[1]);
- p.z = float2fract(point2[2]);
- p2 = AllocTDDDPoint(&p);
-
- face = AllocTDDDFace(AllocTDDDEdge(p0, p1),
- AllocTDDDEdge(p1, p2),
- AllocTDDDEdge(p2, p0));
- AllocTDDDSubGroup(face, texname);
- return TRUE;
- }
-
- bool SetForm(register FILE * outFile, register int *last, register char *ID)
- {
- fwrite("FORM", 1, 4, outFile);
- fwrite(last, 1, 4, outFile);
- *last = ftell(outFile);
- fwrite(ID, 1, 4, outFile);
-
- return TRUE;
- }
-
- bool SetRoot(register FILE * outFile, register int *last, register char *ID)
- {
- fwrite(ID, 1, 4, outFile);
- fwrite(last, 1, 4, outFile);
- *last = ftell(outFile);
-
- return TRUE;
- }
-
- bool SetEndM(register FILE * outFile, register char *ID)
- {
- int len = 0;
-
- fwrite(ID, 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- TDDDnumobjects++;
-
- return TRUE;
- }
-
- bool VerRoot(register FILE * outFile, register int *last, register char *ID)
- {
- int this = ftell(outFile);
-
- fseek(outFile, *last - 8, SEEK_SET);
- *last = this - *last;
- fwrite(ID, 1, 4, outFile);
- fwrite(last, 1, 4, outFile);
- fseek(outFile, this, SEEK_SET);
-
- return TRUE;
- }
-
- bool SetClassName(register FILE * outFile, register char *className)
- {
- int len = 18;
-
- fwrite("NAME", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(className, 1, len, outFile);
-
- return TRUE;
- }
-
- bool SetEntity(register FILE * outFile, register char *variable, register char *content)
- {
- int len = sizeof(struct texture4);
- int nameLen = strlen(content);
- struct texture4 brushTex;
-
- nameLen = ((nameLen + 1) & ~1);
- nameLen++;
- nameLen = ((nameLen + 1) & ~1);
- memset(&brushTex, 0, len);
- strncpy(brushTex.label, variable, 18 + 1);
- brushTex.flags = TXT_DISAB;
- len += brushTex.length = nameLen;
- fwrite("TXT4", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(&brushTex, 1, len - nameLen, outFile);
- fwrite(content, 1, nameLen - 1, outFile);
- fwrite("\0", 1, 1, outFile);
-
- return TRUE;
- }
-
- bool SetBrushes(register FILE * outFile)
- {
- int lastBrush, i;
-
- for(i = 0; i < TDDDgroups; i++) {
- /*
- * write only a subgroup if there are more than one
- * and if the subgroup contains members
- */
- if((TDDDgroups > 1) && (TDDDgroup[i]->count > 0)) {
- SetRoot(outFile, &lastBrush, "FGRP");
- fwrite(TDDDgroup[i], 1, 20 + (sizeof(unsigned short int) * TDDDgroup[i]->count), outFile);
- VerRoot(outFile, &lastBrush, "FGRP");
- strncpy(TDDDbrushes[i].subgrp, TDDDgroup[i]->name, 18);
- }
- SetRoot(outFile, &lastBrush, "BRS5");
- TDDDbrushes[i].length = ((strlen(TDDDgroup[i]->name + 1) + 1) & ~1);
- fwrite(&TDDDbrushes[i], 1, sizeof(struct brush5), outFile);
- fwrite(TDDDgroup[i]->name, 1, TDDDbrushes[i].length, outFile);
- VerRoot(outFile, &lastBrush, "BRS5");
- TDDDgroup[i]->count = 0;
- }
- TDDDgroups = 0;
-
- return TRUE;
- }
-
- bool SetPoints(register FILE * outFile)
- {
- if(TDDDpoints) {
- if(TDDDpoints->pcount) {
- int len = (sizeof(vector) * TDDDpoints->pcount) + sizeof(unsigned short int);
-
- fwrite("PNTS", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(TDDDpoints, 1, len, outFile);
-
- TDDDpoints->pcount = 0;
- }
- }
- return TRUE;
- }
-
- bool SetEdges(register FILE * outFile)
- {
- if(TDDDedges) {
- if(TDDDedges->ecount) {
- int len = sizeof(unsigned short int) * ((TDDDedges->ecount * 2) + 1);
-
- fwrite("EDGE", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(TDDDedges, 1, len, outFile);
-
- TDDDedges->ecount = 0;
- }
- }
- return TRUE;
- }
-
- bool SetFaces(register FILE * outFile)
- {
- if(TDDDfaces) {
- if(TDDDfaces->tcount) {
- int len = sizeof(unsigned short int) * ((TDDDfaces->tcount * 3) + 1);
-
- fwrite("FACE", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(TDDDfaces, 1, len, outFile);
-
- TDDDfaces->tcount = 0;
- }
- }
- return TRUE;
- }
-
- bool SetOtherDefaults(register FILE * outFile, register struct entity *ent)
- {
- double posx = 0;
- double posy = 0;
- double posz = 0;
- int points, len, i;
- struct axis axis = {{0x00010000, 0x00000000, 0x00000000},
- {0x00000000, 0x00010000, 0x00000000},
- {0x00000000, 0x00000000, 0x00010000}};
- struct posi position = {{0, 0, 0}};
- struct shap shape = {SH_AXIS, LP2_NOLAM};
- struct colr colour;
-
- if(ent) {
- position.position.x = float2fract(ent->origin[0]);
- position.position.y = float2fract(ent->origin[1]);
- position.position.z = float2fract(ent->origin[2]);
- if(ent->style) {
- struct int1 light;
-
- shape.lamp = LP2_POINT;
-
- light.intensity.x = light.intensity.y = light.intensity.z = ((unsigned int)ent->light << 22) / 75;
- len = sizeof(struct int1);
- fwrite("INT1", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(&light, 1, len, outFile);
- }
- }
-
- if(TDDDpoints)
- if(TDDDpoints->pcount) {
- struct bbox bound = {{0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF}, {0x8000000, 0x80000000, 0x80000000}};
- struct faceattr *attr = (struct faceattr *)tmalloc((TDDDfaces->tcount * sizeof(rgb)) + sizeof(struct faceattr));
-
- for (points = 0; points < TDDDpoints->pcount; points++) {
- if(TDDDpoints->points[points].x > bound.maxs.x)
- bound.maxs.x = TDDDpoints->points[points].x;
- else if(TDDDpoints->points[points].x < bound.mins.x)
- bound.mins.x = TDDDpoints->points[points].x;
- if(TDDDpoints->points[points].y > bound.maxs.y)
- bound.maxs.y = TDDDpoints->points[points].y;
- else if(TDDDpoints->points[points].y < bound.mins.y)
- bound.mins.y = TDDDpoints->points[points].y;
- if(TDDDpoints->points[points].z > bound.maxs.z)
- bound.maxs.z = TDDDpoints->points[points].z;
- else if(TDDDpoints->points[points].z < bound.mins.z)
- bound.mins.z = TDDDpoints->points[points].z;
- posx += fract2float(TDDDpoints->points[points].x);
- posy += fract2float(TDDDpoints->points[points].y);
- posz += fract2float(TDDDpoints->points[points].z);
- }
- position.position.x = float2fract(posx / TDDDpoints->pcount);
- position.position.y = float2fract(posy / TDDDpoints->pcount);
- position.position.z = float2fract(posz / TDDDpoints->pcount);
-
- bound.maxs.x -= position.position.x;
- bound.maxs.y -= position.position.y;
- bound.maxs.z -= position.position.z;
- bound.mins.x -= position.position.x;
- bound.mins.y -= position.position.y;
- bound.mins.z -= position.position.z;
- len = sizeof(struct bbox);
- fwrite("BBOX", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(&bound, 1, len, outFile);
-
- attr->count = TDDDfaces->tcount;
- for (i = 0; i < TDDDfaces->tcount; i++) {
- attr->attr[i].r = 0xFF;
- attr->attr[i].g = 0xFF;
- attr->attr[i].b = 0xFF;
- }
- len = (TDDDfaces->tcount * sizeof(rgb)) + sizeof(unsigned short int);
- len = ((len + 1) & ~1);
- fwrite("CLST", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(&attr, 1, len, outFile);
- fwrite("RLST", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(&attr, 1, len, outFile);
- fwrite("TLST", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(&attr, 1, len, outFile);
-
- tfree(attr);
- }
-
- len = sizeof(struct axis);
- fwrite("AXIS", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(&axis, 1, len, outFile);
-
- len = sizeof(struct posi);
- fwrite("POSI", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(&position, 1, len, outFile);
-
- len = sizeof(struct shap);
- fwrite("SHP2", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(&shape, 1, len, outFile);
-
- colour.color = 0x00FFFFFF;
- len = sizeof(struct colr);
- fwrite("COLR", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(&colour, 1, len, outFile);
- fwrite("REFL", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(&colour, 1, len, outFile);
- fwrite("TRAN", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(&colour, 1, len, outFile);
- fwrite("SPC1", 1, 4, outFile);
- fwrite(&len, 1, 4, outFile);
- fwrite(&colour, 1, len, outFile);
-
- return TRUE;
- }
-
- /*
- * convert a Imagine-TDDD to a Quake-Map
- */
-
- /* IFF to pseudo IFF */
- int fileIFFtopIFF(FILE *iobFile, struct IFFchunk *IFFroot);
- int memIFFtopIFF(char *iobMem, struct IFFchunk *IFFroot);
- /* pseudo IFF to pseudo Brushes */
- void pIFFtopBrushes(__memBase, struct IFFchunk *IFFroot, int iterVal, struct entity *fillEntity);
- /* pseudo IFF to pseudo Map */
- void pIFFtopMap(__memBase, struct IFFchunk *IFFroot, int iterVal);
-
- void strlwrcpy(register char *dst, register char *src) {
- int i, len = strlen(src);
- for (i = 0; i < len; i++)
- dst[i] = (char)tolower((int)src[i]);
- dst[i] = 0;
- }
-
- int fileIFFtopIFF(register FILE *iobFile, register struct IFFchunk *IFFroot) {
- int processed = 0;
- /*
- * small hack -> IFFroot->iter is IFFpart->next
- */
- struct IFFchunk *IFFpart = (struct IFFchunk *)&IFFroot->size;
-
- while (IFFpart->type != ID_TOBJ) {
- int oldOffs;
-
- /*
- * allocate IFFchunk
- */
- IFFpart->next = (struct IFFchunk *)tmalloc(sizeof(struct IFFchunk));
- IFFpart = IFFpart->next;
- IFFpart->next = 0;
- IFFpart->iter = 0;
- IFFpart->data = 0;
-
- /*
- * read and parse IFFchunk
- */
- fread(IFFpart, 1, 8, iobFile);
- IFFpart->size += 0x00000001;
- IFFpart->size &= 0xFFFFFFFE;
- processed += 8;
- oldOffs = ftell(iobFile);
-
- if(IFFpart->type == ID_OBJ) {
- processed += fileIFFtopIFF(iobFile, IFFpart);
- if((IFFroot->type == ID_TDDD) && (IFFroot->size == processed))
- break;
- }
- else if(IFFpart->type == ID_DESC) {
- processed += fileIFFtopIFF(iobFile, IFFpart);
- if((IFFroot->type == ID_OBJ) && (IFFroot->size == processed))
- break;
- }
- else if(IFFpart->type != ID_TOBJ) {
- processed += IFFpart->size;
- IFFpart->data = (void *)tmalloc(IFFpart->size + 1);
- fread(IFFpart->data, 1, IFFpart->size, iobFile);
- }
- }
-
- return processed;
- }
-
- int memIFFtopIFF(register char *iobMem, register struct IFFchunk *IFFroot) {
- int processed = 0;
- /*
- * small hack -> IFFroot->iter is IFFpart->next
- */
- struct IFFchunk *IFFpart = (struct IFFchunk *)&IFFroot->size;
-
- while (IFFpart->type != ID_TOBJ) {
- /*
- * allocate IFFchunk
- */
- IFFpart->next = (struct IFFchunk *)tmalloc(sizeof(struct IFFchunk));
- IFFpart = IFFpart->next;
- IFFpart->next = 0;
- IFFpart->iter = 0;
- IFFpart->data = 0;
-
- /*
- * read and parse IFFchunk
- */
- memcpy(IFFpart, iobMem, 8);
- iobMem += 8;
- IFFpart->size += 0x00000001;
- IFFpart->size &= 0xFFFFFFFE;
- processed += 8;
-
- if(IFFpart->type == ID_OBJ) {
- processed += memIFFtopIFF(iobMem, IFFpart);
- if((IFFroot->type == ID_TDDD) && (IFFroot->size == processed))
- break;
- }
- else if(IFFpart->type == ID_DESC) {
- processed += memIFFtopIFF(iobMem, IFFpart);
- if((IFFroot->type == ID_OBJ) && (IFFroot->size == processed))
- break;
- }
- else if(IFFpart->type != ID_TOBJ) {
- processed += IFFpart->size;
- IFFpart->data = (void *)tmalloc(IFFpart->size + 1);
- memcpy(IFFpart->data, iobMem, IFFpart->size);
- iobMem += IFFpart->size;
- }
- }
-
- return processed;
- }
-
- void pIFFtopBrushes(__memBase, register struct IFFchunk *IFFroot, register int iterVal, register struct entity *fillEntity) {
- struct IFFchunk *IFFpart = IFFroot;
-
- struct faces *facelist = 0;
- struct posi *origin = 0;
- struct edges *edgelist = 0;
- struct points *pointlist = 0;
- struct brush5 **brushtex = (struct brush5 **)tmalloc(15 * sizeof(struct brush5 *));
- int brushtexs = 0;
- struct facesubgroup **facegroup = (struct facesubgroup **)tmalloc(15 * sizeof(struct facesubgroup *));
- int facegroups = 0;
-
- /*
- * look for other iterated brushes
- */
- while (IFFpart) {
- struct IFFchunk *actIFFpart = IFFpart;
- int indentSpace = iterVal;
-
- while (indentSpace-- > 0) {
- oprintf(" ");
- }
- oprintf("%4s %d bytes\n", (char *)&IFFpart->type, IFFpart->size);
-
- /*
- * all types that are not DESC are for the actBrush
- * after first appeareance of DESC there are only DESCs
- */
- switch (IFFpart->type) {
- case ID_POSI:
- origin = (struct posi *)actIFFpart->data;
- break;
- case ID_FACE:
- facelist = (struct faces *)actIFFpart->data;
- break;
- case ID_EDGE:
- edgelist = (struct edges *)actIFFpart->data;
- break;
- case ID_PNTS:
- pointlist = (struct points *)actIFFpart->data;
- break;
- case ID_FGRP:
- case ID_FGR2:
- case ID_FGR3:
- case ID_FGR4:
- facegroup[facegroups] = (struct facesubgroup *)actIFFpart->data;
- facegroups++;
- break;
- case ID_BRS5:
- brushtex[brushtexs] = (struct brush5 *)actIFFpart->data;
- brushtexs++;
- break;
- case ID_DESC:
- pIFFtopBrushes(bspMem, actIFFpart->iter, iterVal + 1, fillEntity);
- break;
- default:
- tfree(actIFFpart->data);
- break;
- }
- IFFpart = IFFpart->next;
- tfree(actIFFpart);
- }
-
- if(facelist && edgelist && pointlist && brushtexs) {
- int i;
-
- unsigned short int facecnt;
- struct mbrush *actBrush = (struct mbrush *)tmalloc(sizeof(struct mbrush));
- struct mface *checkFace = 0;
- vec3_t middle;
- unsigned short int p0, p1, p2;
- vector *point;
-
- for (facecnt = 0; facecnt < facelist->tcount; facecnt++) {
- p0 = edgelist->edges[facelist->connects[facecnt][0]][0];
- p1 = edgelist->edges[facelist->connects[facecnt][0]][1];
- if((edgelist->edges[facelist->connects[facecnt][1]][0] != p0) &&
- (edgelist->edges[facelist->connects[facecnt][1]][0] != p1))
- p2 = edgelist->edges[facelist->connects[facecnt][1]][0];
- else
- p2 = edgelist->edges[facelist->connects[facecnt][1]][1];
-
- point = &pointlist->points[p0];
- middle[0] += fract2float(point->x);
- middle[1] += fract2float(point->y);
- middle[2] += fract2float(point->z);
- point = &pointlist->points[p1];
- middle[0] += fract2float(point->x);
- middle[1] += fract2float(point->y);
- middle[2] += fract2float(point->z);
- point = &pointlist->points[p2];
- middle[0] += fract2float(point->x);
- middle[1] += fract2float(point->y);
- middle[2] += fract2float(point->z);
- }
- middle[0] /= (facecnt * 3);
- middle[1] /= (facecnt * 3);
- middle[2] /= (facecnt * 3);
-
- for (facecnt = 0; facecnt < facelist->tcount; facecnt++) {
- int j;
- struct mface *actFace = (struct mface *)tmalloc(sizeof(struct mface));
- vec3_t t1, t2, t3;
- float distance;
-
- p0 = edgelist->edges[facelist->connects[facecnt][0]][0];
- p1 = edgelist->edges[facelist->connects[facecnt][0]][1];
- if((edgelist->edges[facelist->connects[facecnt][1]][0] != p0) &&
- (edgelist->edges[facelist->connects[facecnt][1]][0] != p1))
- p2 = edgelist->edges[facelist->connects[facecnt][1]][0];
- else
- p2 = edgelist->edges[facelist->connects[facecnt][1]][1];
-
- point = &pointlist->points[p0];
- actFace->p0[0] = fract2float(point->x);
- actFace->p0[1] = fract2float(point->y);
- actFace->p0[2] = fract2float(point->z);
- point = &pointlist->points[p1];
- actFace->p1[0] = fract2float(point->x);
- actFace->p1[1] = fract2float(point->y);
- actFace->p1[2] = fract2float(point->z);
- point = &pointlist->points[p2];
- actFace->p2[0] = fract2float(point->x);
- actFace->p2[1] = fract2float(point->y);
- actFace->p2[2] = fract2float(point->z);
-
- /*
- * correct to clockwise order
- * planenormal must direct to other side of middle
- * or: the middle must be in the negative side of the room splitted by the plane
- * positive distance between plane and point mean it is on the positive side
- *
- * Erzeugen der Hessischen Normalenform
- * building of hesse-normalform ? to calculate distane between plane and point
- */
- VectorSubtract(actFace->p0, actFace->p1, t1);
- VectorSubtract(actFace->p2, actFace->p1, t2);
- VectorCopy(actFace->p1, t3);
- CrossProduct(t1, t2, actFace->plane.normal);
- VectorNormalize(actFace->plane.normal);
- actFace->plane.dist = DotProduct(t3, actFace->plane.normal);
-
- if((distance = DotProduct(middle, actFace->plane.normal) - actFace->plane.dist) > 0) {
- vec3_t temp;
-
- VectorCopy(actFace->p0, temp);
- VectorCopy(actFace->p2, actFace->p0);
- VectorCopy(temp, actFace->p2);
-
- VectorNegate(actFace->plane.normal);
- actFace->plane.dist = -actFace->plane.dist;
- }
-
- /*
- * elimination doubled faces in resulting only valid brushes
- * equal is: if normal and distance to origin are equal
- * the distance to origin is equal then if the angle between normal and normal of ?-normal is equal
- *
- * in theory in quakeMode, there are no eleminations possible
- */
- checkFace = actBrush->faces;
- while(checkFace) {
- float a, b, c;
- /* Abstand Punkt->Ebene / distances point->plane */
- a = fabs(DotProduct(actFace->p0, checkFace->plane.normal) - checkFace->plane.dist);
- b = fabs(DotProduct(actFace->p1, checkFace->plane.normal) - checkFace->plane.dist);
- c = fabs(DotProduct(actFace->p2, checkFace->plane.normal) - checkFace->plane.dist);
-
- /* if point->plane less than minimum, eleminate them */
- if ((a < ON_EPSILON) && (b < ON_EPSILON) && (c < ON_EPSILON))
- break;
-
- checkFace = checkFace->next;
- }
-
- if(!checkFace) {
- /*
- * get the textures
- */
- for(i = 0; i < facegroups; i++) {
- for(j = 0; j < facegroup[i]->count; j++) {
- if(facegroup[i]->facelist[j] == facecnt)
- break;
- }
- if(j < facegroup[i]->count)
- break;
- }
- for(j = 0; j < brushtexs; j++) {
- if(!strncmp(facegroup[i]->name, brushtex[j]->subgrp, 18))
- break;
- }
- if(j < brushtexs) {
- float zero[2] = {0, 0};
- float one[2] = {1, 1};
- actFace->texinfo = MakeTexinfo(bspMem, brushtex[j]->name, actFace, one, 0, zero);
- }
-
- actFace->next = actBrush->faces;
- actBrush->faces = actFace;
- }
- else
- tfree(actFace);
- }
-
- tfree(facelist);
- tfree(edgelist);
- tfree(pointlist);
- for(i = 0; i < facegroups; i++)
- tfree(facegroup[i]);
- tfree(facegroup);
- for(i = 0; i < brushtexs; i++)
- tfree(brushtex[i]);
- tfree(brushtex);
-
- /*
- * put in brush
- */
- actBrush->next = fillEntity->brushes;
- fillEntity->brushes = actBrush;
- nummapbrushes++;
- }
- else
- eprintf("not enough data to convert brush!\n");
- }
-
- void pIFFtopMap(__memBase, register struct IFFchunk *IFFroot, register int iterVal) {
- struct IFFchunk *IFFpart = IFFroot;
-
- while (IFFpart) {
- struct IFFchunk *actIFFpart = IFFpart;
- int indentSpace = iterVal;
-
- while (indentSpace-- > 0) {
- oprintf(" ");
- }
- oprintf("%4s %d bytes\n", (char *)&actIFFpart->type, actIFFpart->size);
-
- switch (actIFFpart->type) {
- /*
- * only toplevel-processing (iter 0)
- */
- case ID_TDDD:
- /*
- * only toplevel-processing (iter 1)
- */
- case ID_OBJ:
- pIFFtopMap(bspMem, actIFFpart->iter, iterVal + 1);
- break;
- /*
- * only toplevel-processing (iter 2)
- */
- case ID_DESC:
- if(iterVal == 2)
- /* the dummy-axis to save the hierarchie to disk */
- pIFFtopMap(bspMem, actIFFpart->iter, iterVal + 1);
- else {
- if(actIFFpart->iter) {
- struct IFFchunk *Brushes = actIFFpart->iter;
- struct entity *thisEntity;
-
- if (bspMem->nummapentities == bspMem->max_nummapentities)
- ExpandClusters(bspMem, MAP_ENTITIES);
- thisEntity = &bspMem->mapentities[bspMem->nummapentities];
- bspMem->nummapentities++;
-
- while(Brushes) {
- if(Brushes->type == ID_NAME) {
- thisEntity->classname = (char *)tmalloc(strlen(Brushes->data) + 1);
- strlwrcpy(thisEntity->classname, Brushes->data);
- }
- else if(Brushes->type == ID_INT1) {
- struct int1 *inten = (struct int1 *)Brushes->data;
- thisEntity->light = (unsigned char)rint((fract2float(inten->intensity.x) +
- fract2float(inten->intensity.y) +
- fract2float(inten->intensity.z)) / 3);
- }
- else if(Brushes->type == ID_SHP2) {
- struct shap *shape = (struct shap *)Brushes->data;
- if((shape->lamp & LP2_TYPE) != LP2_NOLAM)
- thisEntity->style = 1;
- }
- else if(Brushes->type == ID_POSI) {
- struct posi *origin = (struct posi *)Brushes->data;
- thisEntity->origin[0] = fract2float(origin->position.x);
- thisEntity->origin[1] = fract2float(origin->position.y);
- thisEntity->origin[2] = fract2float(origin->position.z);
- }
- else if(Brushes->type == ID_TXT4) {
- struct texture4 *brushtex = (struct texture4 *)Brushes->data;
- struct epair *lastString;
- struct epair *actString = (struct epair *)tmalloc(sizeof(struct epair));
-
- actString->next = 0;
- actString->key = (char *)tmalloc(brushtex->length + 1);
- strncpy(actString->key, brushtex->name, brushtex->length);
- actString->key[brushtex->length] = 0;
- actString->value = (char *)tmalloc(strlen(brushtex->label) +1);
- strcpy(actString->value, brushtex->label);
-
- if((lastString = thisEntity->epairs)) {
- while(lastString->next)
- lastString = lastString->next;
- lastString->next = actString;
- }
- else
- thisEntity->epairs = actString;
- }
- else if(Brushes->type == ID_DESC) {
- /*
- * after this we get no datas any more
- */
- if(Brushes->iter)
- pIFFtopBrushes(bspMem, Brushes->iter, iterVal + 1, thisEntity);
- }
- Brushes = Brushes->next;
- }
-
- /*
- * for all
- */
- if (VectorZero(thisEntity->origin))
- GetVectorForKey(thisEntity, "origin", thisEntity->origin);
- if(!thisEntity->classname)
- thisEntity->classname = ValueForKey(thisEntity, "classname");
- thisEntity->target = ValueForKey(thisEntity, "target");
- thisEntity->targetname = ValueForKey(thisEntity, "targetname");
-
- /*
- * special for qbsp+light+vis in one part
- */
- if (bspMem->mapOptions & MAP_LOADLIGHTS) {
- if (!(thisEntity->light = FloatForKeyN(thisEntity, "light")))
- if (!(thisEntity->light = FloatForKey(thisEntity, "_light")))
- if (!thisEntity->light)
- thisEntity->light = MAX_MAPLIGHTLEVEL;
- if (!(thisEntity->style = FloatForKey(thisEntity, "style")))
- if (!(thisEntity->style = FloatForKey(thisEntity, "_style")))
- if (!thisEntity->style)
- thisEntity->style = 0;
- if (!thisEntity->angle)
- thisEntity->angle = FloatForKey(thisEntity, "angle");
-
- if (strcmp(thisEntity->classname, "light")) {
- if (!thisEntity->light)
- thisEntity->light = DEFAULTLIGHTLEVEL;
-
- if (thisEntity->targetname[0] && !thisEntity->style) {
- char s[256];
-
- thisEntity->style = LightStyleForTargetname(thisEntity->targetname, TRUE);
- sprintf(s, "%i", thisEntity->style);
- SetKeyValue(thisEntity, "style", s);
- }
- }
- }
- }
- }
- break;
- default:
- break;
- }
- IFFpart = IFFpart->next;
- tfree(actIFFpart->data);
- tfree(actIFFpart);
- }
- }
-
- /*
- the rules:
-
- -the hierarchy:
-
- DESC "world/axis/root" (axis)
- -> acts as global group-manager to save all subhierarchies
- DESC "worldspawn" (axis)
- -> all subdesc's desribes the brushes (objects grouped to axis "worldspawn")
- -> all subdesc's texture info must contain the name of the texture to use and
- the alignment/positioning must be valid
- DESC "info_player_start" (axis)
- -> the axis position describes the players origin
- DESC "standard quake"
- -> will be searched for information
- (eg. DESC "light" (axis with light) is the standard entity "light", parameters
- are parsed out of the axis-informations)
- -> axis that are groupt to a non-worldspawn-entity and that have no brushes
- will beinterpreted as movement-points (?)
- -> the texture-list of an entity will be parsed for key-values (standard-quake
- like "target")
-
- restriction:
-
- dont make objects, that are not convex
- calculation of clockwise point-order goes via middlepoint of object
-
- */
-
- /*
- * ================
- * SaveTDDDFile
- * ================
- */
- bool SaveTDDDFile(__memBase, FILE * outFile)
- {
- struct entity *ent;
- struct epair *ep;
- struct mbrush *b;
- struct mface *f;
- int i;
- struct dmiptexlump_t *head_miptex = (struct dmiptexlump_t *)bspMem->dtexdata;
- struct texinfo *texinfo;
- struct mipmap *miptex;
- int lastTDDD = 0;
- int lastObj = 0;
- int lastWorld = 0;
- int lastRoot = 0;
- int lastDesc = 0;
-
- /*
- hierarchy:
-
- TDDD
- OBJ
- DESC worldaxis
- | DESC worldspawn
- | | DESC model1
- | | +-TOBJ
- | | DESC model2
- | | +-TOBJ
- | | ...
- | +-TOBJ
- | DESC light
- | ...
- +-TOBJ
- */
-
- SetForm(outFile, &lastTDDD, "TDDD");
- SetRoot(outFile, &lastObj, "OBJ ");
-
- SetRoot(outFile, &lastWorld, "DESC");
- SetClassName(outFile, "worldaxis");
- SetOtherDefaults(outFile, 0);
- VerRoot(outFile, &lastWorld, "DESC");
-
- /* set worldspawn as root of all the other models */
- SetRoot(outFile, &lastRoot, "DESC");
- for (i = 0, ent = bspMem->mapentities; i < bspMem->nummapentities; i++, ent++)
- if(!strcmp(ent->classname, "worldspawn"))
- break;
-
- if(i == bspMem->nummapentities) {
- eprintf("SaveTDDDFile: worldspawn not found!\n");
- return FALSE;
- }
-
- SetClassName(outFile, ent->classname);
- for (ep = ent->epairs; ep; ep = ep->next)
- if (strcmp(ep->key, "model"))
- SetEntity(outFile, ep->key, ep->value);
- for (b = ent->brushes; b; b = b->next) {
- for (f = b->faces; f; f = f->next) {
- texinfo = &bspMem->texinfo[f->texinfo];
- miptex = (struct mipmap *)((((unsigned char *)bspMem->dtexdata)) + (head_miptex->dataofs[texinfo->miptex]));
- SaveFace(f->p0, f->p1, f->p2, miptex->name);
- }
- }
- SetPoints(outFile);
- SetEdges(outFile);
- SetFaces(outFile);
- SetBrushes(outFile);
- SetOtherDefaults(outFile, ent);
- VerRoot(outFile, &lastRoot, "DESC");
-
- for (i = 0, ent = bspMem->mapentities; i < bspMem->nummapentities; i++, ent++) {
- int model = 0;
-
- for (ep = ent->epairs; ep; ep = ep->next) {
- if (!strcmp(ep->key, "model")) {
- model = 1;
- break;
- }
- }
-
- if(model && strcmp(ent->classname, "worldspawn")) {
- SetRoot(outFile, &lastDesc, "DESC");
- SetClassName(outFile, ent->classname);
- for (ep = ent->epairs; ep; ep = ep->next)
- if (strcmp(ep->key, "model"))
- SetEntity(outFile, ep->key, ep->value);
- for (b = ent->brushes; b; b = b->next) {
- for (f = b->faces; f; f = f->next) {
- texinfo = &bspMem->texinfo[f->texinfo];
- miptex = (struct mipmap *)((((unsigned char *)bspMem->dtexdata)) + (head_miptex->dataofs[texinfo->miptex]));
- SaveFace(f->p0, f->p1, f->p2, miptex->name);
- }
- }
- SetPoints(outFile);
- SetEdges(outFile);
- SetFaces(outFile);
- SetBrushes(outFile);
- SetOtherDefaults(outFile, ent);
- VerRoot(outFile, &lastDesc, "DESC");
- SetEndM(outFile, "TOBJ");
- }
- }
- SetEndM(outFile, "TOBJ");
-
- for (i = 0, ent = bspMem->mapentities; i < bspMem->nummapentities; i++, ent++) {
- int model = 0;
-
- for (ep = ent->epairs; ep; ep = ep->next) {
- if (!strcmp(ep->key, "model")) {
- model = 1;
- break;
- }
- }
-
- if(!model && strcmp(ent->classname, "worldspawn")) {
- SetRoot(outFile, &lastDesc, "DESC");
- SetClassName(outFile, ent->classname);
- for (ep = ent->epairs; ep; ep = ep->next)
- if (strcmp(ep->key, "model"))
- SetEntity(outFile, ep->key, ep->value);
- for (b = ent->brushes; b; b = b->next) {
- for (f = b->faces; f; f = f->next) {
- texinfo = &bspMem->texinfo[f->texinfo];
- miptex = (struct mipmap *)((((unsigned char *)bspMem->dtexdata)) + (head_miptex->dataofs[texinfo->miptex]));
- SaveFace(f->p0, f->p1, f->p2, miptex->name);
- }
- }
- SetPoints(outFile);
- SetEdges(outFile);
- SetFaces(outFile);
- SetBrushes(outFile);
- SetOtherDefaults(outFile, ent);
- VerRoot(outFile, &lastDesc, "DESC");
- SetEndM(outFile, "TOBJ");
- }
- }
- SetEndM(outFile, "TOBJ");
- VerRoot(outFile, &lastObj, "OBJ ");
- VerRoot(outFile, &lastTDDD, "TDDD");
-
- mprintf("----- SaveTDDDFile -------\n");
- mprintf("%5i points\n", TDDDnumpoints);
- mprintf("%5i edges\n", TDDDnumedges);
- mprintf("%5i faces\n", TDDDnumfaces);
- mprintf("%5i groups\n", TDDDnumgroups);
- mprintf("%5i objects\n", TDDDnumobjects);
-
- return TRUE;
- }
-
- /*
- * ================
- * LoadTDDDFile
- * ================
- */
- bool LoadTDDDFile(__memBase, char *tdddBuf)
- {
- struct IFFheader IFFfile = {0, 0, 0};
- struct IFFchunk *IFFroot = (struct IFFchunk *)tmalloc(sizeof(struct IFFchunk));
-
- memcpy(&IFFfile, tdddBuf, 12);
- tdddBuf += 12;
- IFFroot->type = IFFfile.type;
- IFFroot->size = IFFfile.size - 4;
- IFFroot->next = 0;
- IFFroot->iter = 0;
- IFFroot->data = 0;
- memIFFtopIFF(tdddBuf, IFFroot);
- pIFFtopMap(bspMem, IFFroot, 0);
- MatchTargets(bspMem);
-
- mprintf("----- LoadTDDDFile -------\n");
- mprintf("%5i brushes\n", nummapbrushes);
- mprintf("%5i entities\n", bspMem->nummapentities);
- mprintf("%5i miptex\n", bspMem->nummaptexstrings);
- mprintf("%5i texinfo\n", bspMem->numtexinfo);
-
- return TRUE;
- }
-